Skip to content

fix(e2e): honor the live_download exclusion; fix runtime plugin search path - #68

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/odds-sods-pm-goals-xktszo
Jul 9, 2026
Merged

fix(e2e): honor the live_download exclusion; fix runtime plugin search path#68
hyperpolymath merged 1 commit into
mainfrom
claude/odds-sods-pm-goals-xktszo

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Follow-up to #67. The e2e workflow has been red on main for weeks — first at compile (--warnings-as-errors), which #67 fixed; with compile green, the runtime-api job then failed on {:error, {:no_plugin, "zig"}} from tests that were never meant to run there. Two pre-existing defects, both fixed at source:

1. Tag taxonomy — download tests ran in PR CI despite the exclusion

The live-download tests carried both @tag :external_api and @tag :live_download. ExUnit's --include re-includes tests dropped by --exclude, so

mix test --include external_api --exclude live_download

ran the ~10–50MB download tests that e2e.yml's own header reserves for manual dispatch. They now carry only :live_download (run manually via --include live_download), matching the taxonomy defined at the top of the test file.

2. Plugin search path — Manager.install couldn't resolve plugins from a checkout

@plugin_search_dirs was a module attribute, so :code.priv_dir(:opsm) was frozen at compile time, pointing inside whatever _build compiled the module — its own comment said "resolved at runtime", an intent that never held. Result: runtime/core/*.ncl plugins were unreachable from any repo checkout (this also breaks the opsm runtime install dogfooding path that reads opsm.toml [runtime]).

Search dirs are now computed per call, with repo-checkout fallbacks (cwd/../runtime/core under mix, cwd/runtime/core as escript) and a fail-safe guard on :code.priv_dir/1. find_plugin_ncl/1 is @doc false public with unit tests covering checkout resolution.

Also hardened: System.cmd("nickel", …) raises ErlangError :enoent when nickel isn't installed — now returns {:error, {:nickel_not_installed, tool}}.

Verified (OTP 28.3.1 / Elixir 1.19.5)

  • mix compile --warnings-as-errors — green
  • mix test test/opsm/runtime/manager_test.exs — 17/17 (2 new find_plugin_ncl tests)
  • The exact runtime-api CI command — 9 tests, 0 failures, 6 excluded, live against ziglang.org / go.dev / nodejs.org; both previously-failing tests correctly excluded

Note: the branch was restarted from main after #67's squash-merge (the old remote branch was auto-deleted on merge), so this PR contains only the follow-up commit.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kq24sZCEohSrNFXSuEuz6C


Generated by Claude Code

… plugin search path

The e2e workflow has been red on main for weeks — first at compile
(warnings-as-errors), fixed by #67; with compile green the runtime-api
job then failed on {:error, {:no_plugin, "zig"}} from tests that were
never meant to run there. Two pre-existing defects:

- Tag taxonomy: the live-download tests carried BOTH @tag :external_api
  and @tag :live_download. ExUnit's --include re-includes tests dropped
  by --exclude, so 'mix test --include external_api --exclude
  live_download' ran the ~10-50MB download tests the workflow header
  explicitly reserves for manual dispatch. Live-download tests now carry
  only :live_download (run them via --include live_download).

- Plugin search path: @plugin_search_dirs was a module attribute, so
  :code.priv_dir(:opsm) was frozen at COMPILE time pointing inside
  whatever _build compiled the module (its own comment said 'resolved
  at runtime' — that intent never held). Manager.install could not
  resolve runtime/core/*.ncl plugins from a repo checkout at all.
  Search dirs are now computed per call, with repo-checkout fallbacks
  (cwd/../runtime/core for mix, cwd/runtime/core for the escript) and a
  fail-safe guard on :code.priv_dir/1. find_plugin_ncl/1 is @doc false
  public with unit tests covering checkout resolution.

- Hardening: System.cmd("nickel", ...) raises ErlangError :enoent when
  nickel is absent — now returns {:error, {:nickel_not_installed, tool}}.

Verified on OTP 28.3.1 / Elixir 1.19.5: compile --warnings-as-errors
green; manager tests 17/17; the exact runtime-api CI command now runs
9 lightweight API tests (all passing live against ziglang.org, go.dev,
nodejs.org) with all 6 live-download tests excluded.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kq24sZCEohSrNFXSuEuz6C
@hyperpolymath
hyperpolymath marked this pull request as ready for review July 9, 2026 23:39
@hyperpolymath
hyperpolymath merged commit 6df4e8d into main Jul 9, 2026
25 of 27 checks passed
@hyperpolymath
hyperpolymath deleted the claude/odds-sods-pm-goals-xktszo branch July 9, 2026 23:40
hyperpolymath added a commit that referenced this pull request Jul 17, 2026
…crawl on warm-cache miss (#70)

Closes the loop on the e2e redness: `main`'s e2e run #47 failed on both
attempts (I re-ran its failed jobs to confirm determinism). Local
reproduction on the exact toolchain identified two causes — one
introduced by #68, one long-latent:

## 1. `:live_download` leaked into the default suite (regression from
#68)

`test_helper.exs` never excluded `:live_download` — those tests were
only kept out of `mix test` by riding on their `:external_api` tag. When
#68 removed that tag (correctly, to fix the `--include`/`--exclude`
interaction), the ~10–50MB download tests fell into the **default**
suite, where the e2e-opsm "Run all tests" step runs them on runners
without nickel → `{:error, {:nickel_not_installed, "zig"}}` × 2. Fix:
exclude `:live_download` explicitly in `ExUnit.start/1`; run them
deliberately via `--include live_download`.

## 2. `HyperpPolymathForge.fetch_package/2` re-crawled the GitHub org on
every miss

A per-name cache miss triggered `refresh_index()` — a full
unauthenticated org listing — even when the index was already populated.
Any absent package name burned rate limit, and on CI runners the 403
surfaced as `{:error, {:http_error, 403}}` instead of `{:error,
:not_found}`. The ETS-seeded test at `hyperpolymath_forge_test.exs:321`
documents the intended contract ("cache is non-empty, so refresh_index
won't fire") — the implementation just never honored it. A miss against
a warm cache now returns `:not_found` with no network I/O; a cold cache
still refreshes and still propagates refresh errors. The warmth
criterion mirrors the existing `ensure_index/0`.

## Verified (OTP 28.3.1 / Elixir 1.19.5)

- `mix compile --warnings-as-errors` — clean
- Full default suite (`mix test`) — **807 tests, 0 failures**
(previously 2)
- e2e step (`--include e2e --include integration`) — 55/55
- runtime-api step (`--include external_api --exclude live_download`) —
9/9, 6 excluded
- `just toolchain-check` — green

With this, all three e2e workflow test commands pass locally against
`main`'s toolchain; the only expected remaining red on this PR is the
pre-existing governance ReScript policy check (fails identically on
`main`; owner-decision).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Kq24sZCEohSrNFXSuEuz6C

---
_Generated by [Claude
Code](https://claude.ai/code/session_01Kq24sZCEohSrNFXSuEuz6C)_

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants